/*
 * NetworkStats.java
 *
 * Created on Dec 21, 2011
 *
 * Copyright (c) 2011 Artur Rataj.
 *
 * This code is distributed under the terms of the GNU Library
 * General Public License, either version 3 of the license or, at
 * your option, any later version.
 */

package pl.gliwice.iitis.spatialnn.network.construct;

import java.util.*;
import pl.gliwice.iitis.spatialnn.network.Network;
import pl.gliwice.iitis.spatialnn.network.NeuronType;

/**
 * Describes statistical parameters of a neural network
 * .
 * @author Artur Rataj
 */
public class NetworkStats {
    /**
     * The output membrane.
     */
    public MembraneStats membrane;
    /**
     * Subsequent layers since the output membrane.
     */
    public List<LayerStats> layers;
    /**
     * Value of <code>turnNum</code>, that means no turn in the network.
     */
    public static final int TURN_NUM_NONE = -2;
    /**
     * Number of the layer, whose inputs are turn ones. -1 for an output membrabne,
     * the default of <code>TURN_NUM_NONE</code> for no turn in the network.
     */
    int turnLayerNum;
    /**
     * Depth of the turn, that is, number of repeated turn sections; 0 if
     * <code>layerNum == TURN_NUM_NONE</code>.
     */
    int turnSectionNum;
    /**
     * Size of a single turn section; 0 if <code>layerNum == TURN_NUM_NONE</code>.
     */
    int turnSectionSize;
    /**
     * How much of each section's lower layers to skip when connecting with the lower section,
     * if any; 0 for no skipping of layers or if <code>layerNum == TURN_NUM_NONE</code>.
     * The skipped layers output only to the turn layer.
     */
    int turnSectionSkip;
    
    /**
     * Creates a new instance of <code>NetworkStats</code>.
     * 
     */
    public NetworkStats() {
        layers = new ArrayList<>();
        turnLayerNum = TURN_NUM_NONE;
        turnSectionNum = 0;
        turnSectionSize = 0;
        turnSectionSkip = 0;
    }
    /**
     * Adds statistics of a next layer of neurons.
     * 
     * @param layer statistica parameters of the layer to add
     */
    public void addLayer(LayerStats layer) {
        layers.add(layer);
    }
    /**
     * Adds statistics of a next layer of neurons, derived from defaults of
     * a neuron type.
     * 
     * @param neuronType type of neurons in the layer, whose statistics to add
     * @param outputLayerNum to which layer neurons in the layer output, -1
     * for an output membrane
     * @param turnInputs passed to <code>neuronType.getConstructionParams(turnInputs)</code>
     */
    public void addLayer(NeuronType neuronType, int outputLayerNum,
            boolean turnInputs) {
        addLayer(new LayerStats(neuronType, outputLayerNum,
                neuronType.getConstructionParams(turnInputs)));
    }
    /**
     * Sets inputs to a given layer or membrane as turn ones.
     * 
     * @param layerNum number of a layer, -1 for an output membrane,
     * the default of <code>TURN_NUM_NONE</code> for no turn
     * @param sectionNum depth of the turn, that is, number of repeated turn
     * sections; 0 if <code>layerNum == TURN_NUM_NONE</code>
     * @param sectionSize size of a single turn section; 0 if
     * <code>layerNum == TURN_NUM_NONE</code>.
     * @param sectionSkip how much of section's lower layers to skip when connecting
     * with the lower section; 0 for no skipping of layers or if
     * <code>layerNum == TURN_NUM_NONE</code>; the skipped layers output
     * only to the turn layer
     */
    public void setTurn(int layerNum, int sectionNum, int sectionSize, int sectionSkip) {
        turnLayerNum = layerNum;
        turnSectionNum = sectionNum;
        turnSectionSize = sectionSize;
        turnSectionSkip = sectionSkip;
        if(turnLayerNum == TURN_NUM_NONE &&
                (turnSectionNum != 0 || turnSectionSize != 0 || turnSectionSkip != 0))
            throw new RuntimeException("invalid turn parameters");
    }
}
